/**
 * @(#) DefaultChannelInboundHandlerAdapter.java RabbitDB
 */
package cn.rabbitdb.faced.server;

import cn.rabbitdb.faced.server.utils.Bytes;
import cn.rabbitdb.protocol.mysql41.MySQLCapabilityFlags;
import cn.rabbitdb.protocol.mysql41.MySQLCommandPacket;
import cn.rabbitdb.protocol.mysql41.MySQLErrorPacket;
import cn.rabbitdb.protocol.mysql41.MySQLHandshark41;
import cn.rabbitdb.protocol.mysql41.MySQLHandshark41Response;
import cn.rabbitdb.protocol.mysql41.MySQLOkPacket;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author 智慧工厂@
 *
 */
@RequiredArgsConstructor
@Getter
@Slf4j
class DefaultChannelInboundHandlerAdapter extends ChannelInboundHandlerAdapter {
	private final Lifecycle boundServer;

	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		/**
		 * 根据MYSQL41协议: 随即生成密码加密种子
		 */
		byte[] authPluginDataPart1 = Bytes.random(8);
		byte[] authPluginDataPart2 = Bytes.random(12);
		/**
		 * 写入会话管理器
		 */
		SessionManager.instance.getSessions().put(ctx, new Session(ctx, authPluginDataPart1, authPluginDataPart2));
		/**
		 * 根据MYSQL41协议: 当客户端连接后,立即发送握手包
		 */
		MySQLHandshark41 handshark = new MySQLHandshark41(0, 10, "RabbitDB-1.0.0", (int) Thread.currentThread().getId(),
				authPluginDataPart1, -15361, 33 /* UTF-8 */, 2, 21, authPluginDataPart2, "caching_sha2_password");
		System.out.println(handshark);
		Bytes.dumpBuffer(handshark.getMySQLMessageWriter().getBuffer());
		ctx.writeAndFlush(handshark.getMySQLMessageWriter().getBuffer());
	}

	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		ByteBuf buf = (ByteBuf) msg;
		log.info("################");
		// Bytes.dumpBuffer(buf.duplicate());
		Session session = SessionManager.instance.getSessions().get(ctx);
		if (!session.isAuthorized()) {
			MySQLHandshark41Response handsharkResponse = new MySQLHandshark41Response(buf);
			log.info("current mysql clinet auth plugin is {}", handsharkResponse.getClientPluginName());
			if (!handsharkResponse.getClientPluginName().equalsIgnoreCase("caching_sha2_password")) {
				MySQLErrorPacket err = new MySQLErrorPacket(handsharkResponse.getPacketId() + 1, 1045,
						"RabbitDB Required only :caching_sha2_password");
				ByteBuf out = err.getMySQLMessageWriter().getBuffer();
				Bytes.dumpBuffer(out.duplicate());
				ctx.writeAndFlush(out);
				return;
			}

			/**
			 * 发送OK包
			 */
			MySQLOkPacket ok = new MySQLOkPacket(handsharkResponse.getPacketId() + 1,
					MySQLCapabilityFlags.CLIENT_PROTOCOL_41, 0, 0, 0, 2, "");
			ByteBuf out = ok.getMySQLMessageWriter().getBuffer();
			Bytes.dumpBuffer(out.duplicate());
			ctx.writeAndFlush(out);
			session.setAuthorized(true);
			return;
		}

		/**
		 * 处理认证后的操作
		 */
		Bytes.dumpBuffer(buf.duplicate());
		MySQLCommandPacket commandPacket = new MySQLCommandPacket(buf);
		log.info("command packet is {}", commandPacket);
	}
}
